<template>
  <div class="my-image-box">
    <div class="image-box">
      <div class="shape-circle" v-if="imageConfig.shape === 'circle'">
        <div class="image-upload-box" @click="changeImage" style="border-radius: 50%">
          <div class="image-show-box">
            <el-avatar :size="imageConfig.size" :src="imageUrl">
              <div class="image-slot">
                <el-icon>
                  <icon-picture/>
                </el-icon>
              </div>
            </el-avatar>
          </div>
        </div>
      </div>
      <div class="shape-square" v-else-if="imageConfig.shape === 'square'">
        <div class="image-upload-box" @click="changeImage">
          <div class="image-show-box" style="">
            <el-image :src="imageUrl" :style="getWeightAndHeight()">
              <template #error>
                <div class="image-slot">
                  <el-icon :style="getImageErrorSize()">
                    <icon-picture/>
                  </el-icon>
                </div>
              </template>
            </el-image>
          </div>
        </div>
      </div>
      <div v-else>
        图片形状设置有误，请检查
      </div>
    </div>
    <div class="image-upload-dialog-box">
        <my-image-cropper v-model:imageUploadShow="imageCropperShow"
                          action="/_api/portal/image" @upload="upload"
                          :shape="config.shape"
                          :title="title"
                          :width="itemNotNull(config.size)?config.size*3:config.width*3"
                          :cropper-options="cropper" :pxToRem="pxToRem"/>
    </div>
  </div>
</template>

<script>
import {Picture as IconPicture} from '@element-plus/icons-vue'
import MyImageCropper from "@/components/image/myImageCropper.vue";

export default {
  components: {
    MyImageCropper,
    IconPicture: IconPicture
  },
  emits:["updateImg"],
  props: {
    modelValue: {
      type: String,
      default: "",
    },
    title: {
      type: String,
      default: "上传图片"
    },
    imageConfig: {
      type: Object,
      default: {
        shape: "square", // square circle
        radius: 0,
        size: null,//单位PX 有size配置，  width 和height 将会失效 且 shape等于circle，仅仅会生效此属性
        width: 100,//单位PX
        height: 60,//单位PX
        fit: "cover", //图片如何适应到容器框，同原生 object-fit。  'fill', 'contain', 'cover', 'none', 'scale-down',
        lazy: true,
        alt: "图片",
      }
    },
    cropperConfig: {
      type: Object,
      default: {}
    }
  },
  data() {
    return {
      pxToRem: 16,
      imageUrl: "",
      imageCropperShow: false,
      config: {
        shape: "square", // square circle
        radius: 0,
        size: "",//单位PX 有size配置，  width 和height 将会失效 且 shape等于circle，仅仅会生效此属性
        width: 100,//单位PX
        height: 60,//单位PX
        fit: "cover", //图片如何适应到容器框，同原生 object-fit。  'fill', 'contain', 'cover', 'none', 'scale-down',
        lazy: true,
        alt: "图片",
      },
      cropper: {
        autoCropWidth: 200,
        autoCropHeight: 100
      }
    }
  },
  watch: {
    "url": {
      handler(newVal) {
        this.imageUrl = newVal;
      }
    },
    "imageConfig": {
      handler(newVal) {
        this.initImageConfig(newVal);
      }
    }
  },
  beforeMount() {
    this.imageUrl = this.modelValue;
    this.initImageConfig(this.imageConfig);
  },
  methods: {
    initCropperConfig() {
      if (this.itemNotNull(this.config.size)) {
        this.cropper.autoCropWidth = this.config.size;
        this.cropper.autoCropHeight = this.config.size;
      } else {
        this.cropper.autoCropWidth = this.config.width;
        this.cropper.autoCropHeight = this.config.height;
      }
      Object.assign(this.cropper, this.cropperConfig);
    },
    initImageConfig(newImageConfig) {
      if (this.itemNotNull(newImageConfig.shape)) {
        this.config.shape = newImageConfig.shape;
      }

      if (this.itemNotNull(newImageConfig.radius)) {
        this.config.radius = newImageConfig.radius;
      }

      if (this.itemNotNull(newImageConfig.size)) {
        this.config.size = newImageConfig.size;
      }

      if (this.itemNotNull(newImageConfig.width)) {
        this.config.width = newImageConfig.width;
      }

      if (this.itemNotNull(newImageConfig.height)) {
        this.config.height = newImageConfig.height;
      }

      if (this.itemNotNull(newImageConfig.fit)) {
        this.config.fit = newImageConfig.fit;
      }

      if (this.itemNotNull(newImageConfig.lazy)) {
        this.config.lazy = newImageConfig.lazy;
      }

      if (this.itemNotNull(newImageConfig.alt)) {
        this.config.alt = newImageConfig.alt;
      }

      this.initCropperConfig();
    },
    itemNotNull(item) {
      return !(item === '' || item === null || item === undefined);
    },
    upload(image) {
      if (image.url !== null && image.url !== undefined) {
        this.imageUrl = image.url;
      } else {
        this.imageUrl = image.blob;
      }
      this.$emit('update:modelValue', this.imageUrl);
      this.$emit('updateImg', this.imageUrl);
    },
    changeImage() {
      this.imageCropperShow = true;
    },
    getWeightAndHeight() {
      if (!this.config.size) {
        return 'width:' + this.config.width / this.pxToRem + 'rem;height:' + this.config.height / this.pxToRem + 'rem;';
      } else {
        return 'width:' + this.config.size / this.pxToRem + 'rem;height:' + this.config.size / this.pxToRem + 'rem;';
      }
    },
    getImageErrorSize() {
      if (!this.config.size) {
        let size = this.config.width > this.config.height ? this.config.height : this.config.width;
        return 'font-size:' + size / this.pxToRem / 2 + 'rem;';
      } else {
        return 'font-size:' + this.config.size / this.pxToRem / 2 + 'rem;';
      }
    }
  }
}
</script>

<style scoped lang="scss">
.my-image-box {
  .image-upload-box {
    padding: .2rem;
    border: #CDD0D6 .15rem dashed;
    cursor: pointer;

    .el-image {
      display: flex !important;
      align-items: center;
      justify-content: center;
    }
  }

  .image-upload-box:hover {
    border: #409EFF .15rem dashed;
  }
}
</style>